package fr.kraml;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.http.*;
import org.apache.http.client.entity.*;
import org.apache.http.client.methods.*;
import org.apache.http.conn.params.*;
import org.apache.http.impl.client.*;
import org.apache.http.message.*;
import org.apache.http.params.*;
import org.apache.http.client.CookieStore;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

public class KramlService extends Service {

	boolean prox = false;
	NotificationManager mNM;

	boolean mConnected = false;
	String mStatus = "";
	String mRoom = "";

	String me = "";

	public BDD bdd = new BDD();

	static final int GET_ALL = 0;
	static final int MSG_MESSAGE = 1;
	static final int MSG_LOGIN = 2;
	static final int MSG_LOGOUT = 3;
	static final int MSG_JOIN_ROOM = 4;
	static final int MSG_ROOM_LIST = 5;
	static final int MSG_GROUPCHAT = 6;
	static final int MSG_LOAD_BDD_MESSAGES = 7;
	static final int MSG_LOAD_BDD_PARTICIPANTS = 8;

	CookieStore cookieStore;
	String userAgent = "API Android to KramL";
	String apiUrl = "http://api.kraml.fr/";

	Notification noti;

	final Messenger mMessenger = new Messenger(new IncomingHandler());
	Messenger client;

	private static boolean isRunning = false;

	@SuppressLint("HandlerLeak")
	class IncomingHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			// client = msg.replyTo;
			// Log.d("KramL", "Client attached");
			switch (msg.what) {
			case MSG_MESSAGE:
				client = msg.replyTo;
				Log.d("KramL", "! Client attached");
				break;
			case MSG_LOGIN:
				String user = msg.getData().getString("user");
				String pass = msg.getData().getString("password");
				mRoom = msg.getData().getString("room");
				/*
				 * KramlParcelableLogin data = (KramlParcelableLogin) msg
				 * .getData().getParcelable("login");
				 */
				Log.i("KramlService", "Login : " + user + " / " + pass);
				login(user, pass);
				break;
			case MSG_LOGOUT:
				Log.i("KramlService", "Logout : ");
				disconnect();
				break;
			case MSG_JOIN_ROOM:
				String room = msg.getData().getString("room");
				Log.i("KramlService", "JoinRoom : " + room);
				;
				joinroom(room);
				break;
			case MSG_ROOM_LIST:
				roomlist();
				break;
			case GET_ALL:
				send_all_data();
				break;
			case MSG_GROUPCHAT:
				String text = msg.getData().getString("text");
				sendToRoom(text);
				break;
			case MSG_LOAD_BDD_MESSAGES:
				Iterator<RoomMessage> i = bdd.room_messages.iterator();
				while (i.hasNext()) {
					RoomMessage rm = (RoomMessage) i.next();
					Bundle b = new Bundle();
					b.putString("from", rm.from);
					b.putString("text", rm.mess);
					b.putString("color", rm.color);
					msg = Message.obtain(null, KramlMain.MSG_GROUPCHAT);
					msg.setData(b);
					try {
						client.send(msg);
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				break;
			case MSG_LOAD_BDD_PARTICIPANTS:
				Iterator<Participant> it = bdd.participants.iterator();
				while (it.hasNext()) {
					Participant p = (Participant) it.next();
					Bundle b = new Bundle();
					b.putString("from", p.username);
					b.putString("show", p.show);
					b.putString("status", p.status);
					b.putString("age", Integer.toString(p.age));
					b.putString("sex", p.sex);
					b.putString("location", p.location);
					b.putString("avatar", p.avatar);
					b.putBoolean("BDD", true);
					msg = Message.obtain(null, KramlMain.MSG_PRESENCE);
					msg.setData(b);
					try {
						client.send(msg);
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				break;
			default:
				super.handleMessage(msg);
			}
		}
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		// Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

		mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

		Intent i = new Intent(this, KramlMain.class);
		PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

		noti = new NotificationCompat.Builder(this).setContentTitle("KramL")
				.setContentText("Service running")
				.setSmallIcon(R.drawable.ic_launcher).setContentIntent(pi)
				.setTicker("KramL service is running").build();

		i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_SINGLE_TOP);

		// PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

		/*
		 * noti.setLatestEventInfo(this, "Fake Player",
		 * "Now Playing: \"Ummmm, Nothing\"", pi);
		 */
		noti.flags |= Notification.FLAG_NO_CLEAR;

		startForeground(1, noti);
		isRunning = true;
		// mNM.notify(R.string.notif_name, noti);

		// sendMessageToUI("Test1", "Value1");

		return super.onStartCommand(intent, flags, startId);
	}

	public void send_all_data() {
		Bundle b = new Bundle();
		b.putBoolean("connected", mConnected);
		Message msg = Message.obtain(null, KramlMain.MSG_ALL_CONNECTED);
		msg.setData(b);
		try {
			client.send(msg);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (!mConnected)
			return;

		// Room name
		b = new Bundle();
		b.putString("room_name", bdd.room_name);
		msg = Message.obtain(null, KramlMain.MSG_ROOM_INFO);
		msg.setData(b);
		try {
			client.send(msg);
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Room messages
		/*
		 * Iterator<RoomMessage> i = bdd.room_messages.iterator(); while
		 * (i.hasNext()) { RoomMessage rm = (RoomMessage) i.next(); b = new
		 * Bundle(); b.putString("from", rm.from); b.putString("text", rm.mess);
		 * b.putString("color", rm.color); msg = Message.obtain(null,
		 * KramlMain.MSG_GROUPCHAT); msg.setData(b); try { client.send(msg); }
		 * catch (RemoteException e) { // TODO Auto-generated catch block
		 * e.printStackTrace(); } }
		 */

	}

	public static boolean isRunning() {
		return isRunning;
	}

	@Override
	public void onCreate() {
		// mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

		// Display a notification about us starting.
		// showNotification();
	}

	@Override
	public void onDestroy() {
		// Cancel the persistent notification.
		// mNM.cancel(R.string.notif_name);
		// Log.i("KramlService", "Logout");
		// disconnect();

		isRunning = false;
		// Tell the user we stopped.
		Toast.makeText(this, R.string.notif_name, Toast.LENGTH_SHORT).show();
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mMessenger.getBinder();
	}

	public void roomlist() {
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "rooms"));
	}

	public void login(String user, String password) {
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "connect", new String[][] {
						{ "user", user }, { "password", password } }));
	}

	public void sendToRoom(String message) {
		// message = URLEncoder.encode(message);
		// message = realEncodeBeforePost(message);
		// new AjaxCall().execute(new KramL_HttpPost(apiUrl + "room_message",
		// new String[][] { { "text", message } }));

		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "room_message", new String[][] { {
						"text", message } }));

		// txt_send_message.setText("");
	}

	public void sendToPV(String dest, String message) {
		// TODO Auto-generated method stub
		// message = URLEncoder.encode(message);
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "private_message", new String[][] {
						{ "user", dest }, { "message", message } }));
	}

	public void joinroom(String roomname) {
		// roomname = URLEncoder.encode(roomname);
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "join", new String[][] {
						{ "room_name", roomname }, { "room_lang", "fr" } }));
	}

	public void ping() {
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "ping"));
		// return postWithHttpClient("http://www.kraml.fr/v2/api/"
		// + this.connected_user + "/ping", new String[][] {});
	}

	public void setStatus() {
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "status", new String[][] {
				// { "show", "chat" }, { "status", "AndroRocks" } }));
				{ "show", "chat" } }));
		// return postWithHttpClient("http://www.kraml.fr/v2/api/"
		// + this.connected_user + "/ping", new String[][] {});
	}

	public void disconnect() {
		new AjaxCall().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
				new KramL_HttpPost(apiUrl + "disconnect"));

		// new AjaxCall().execute("http://www.kraml.fr/v2/api/"
		// + this.connected_user + "/disconnect");
	}

	/*
	 * void sendToastToClient(String txt) { // Message to Main Message msg =
	 * Message.obtain(null, KramlMain.MSG_TOAST); Bundle b = new Bundle();
	 * b.putParcelable("toast", (Parcelable) new KramlParcelableLogin(txt, ""));
	 * msg.setData(b); try { client.send(msg); } catch (RemoteException e) { //
	 * TODO Auto-generated catch block e.printStackTrace(); } }
	 */

	private void sendMessageToUI(int id) {
		try {
			Message msg = Message.obtain(null, id);
			client.send(msg);
		} catch (RemoteException e) {

		}
	}

	private void sendToastToUI(String value) {
		// for (int i=mClients.size()-1; i>=0; i--) {

		// }
	}

	int parseResponse(String response) {
		// int ret = 0;
		boolean ping_again = false;
		// boolean debug = true;

		// sendToastToClient("DEBUG : " + response);
		// sendToastToUI("DEBUG : " + response);

		Log.i("KramlService", "Response : " + response);

		try {
			JSONArray json_response = new JSONArray(response);

			// Reponse vide ^^ pas normal !
			if (json_response.length() == 0) {
				/*
				 * showToast("DEBUG : " + json_response.toString(),
				 * Toast.LENGTH_LONG);
				 */
				return -1;
			}

			for (int i = 0; i < json_response.length(); i++) {
				JSONObject item = json_response.getJSONObject(i);
				String response_type = item.getString("response");

				if (item.has("reping") && item.getBoolean("reping")) {
					ping_again = true;
					// txt_output.append("On ping again !!\n");
				}

				if (response_type.equals("pinged")) {
					/*
					 * if (item.getBoolean("reping")) { ping_again = true; //
					 * txt_output.append("On ping again !!\n"); }
					 */
					// TODO
				} else if (response_type.equals("authentication_failed")) {
					sendToastToUI("Accès impossible : "
							+ item.getString("reason"));
					// Message to Main
					// sendToastToClient("Mauvais mot de passe");
					/*
					 * showToast("DEBUG : " + item.getString("reason"),
					 * Toast.LENGTH_LONG);
					 */
				} else if (response_type.equals("connected")) {
					mConnected = true;
					me = item.getString("username");
					sendMessageToUI(KramlMain.MSG_CONNECTED);

					// sendToastToClient("Connexion OK");
					/*
					 * showToast("DEBUG : " + item.getString("username"),
					 * Toast.LENGTH_LONG);
					 */
					setStatus();
					joinroom(mRoom);
					ping();
				} else if (response_type.equals("userCreated")) {
					sendToastToUI("Utilisateur créé avec succès");
					/*
					 * showToast("Utilisateur créé avec succès",
					 * Toast.LENGTH_LONG);
					 */
				} else if (response_type.equals("presence")) {
					JSONArray presences = item.getJSONArray("presences");
					for (int j = presences.length() - 1; j >= 0; j--) {
						JSONObject pres = presences.getJSONObject(j);
						Bundle b = new Bundle();
						String from = pres.getString("from");
						String show = pres.getString("show");
						String status = "";
						if (pres.has("status"))
							status = pres.getString("status");
						String age = "0";
						if (pres.has("age"))
							age = pres.getString("age");
						String sex = "";
						if (pres.has("sex"))
							sex = pres.getString("sex");
						String location = "";
						if (pres.has("location"))
							location = pres.getString("location");
						String avatar = "";
						if (pres.has("avatarSmall"))
							avatar = pres.getString("avatarSmall");

						b.putString("from", from);
						b.putString("show", show);
						b.putString("status", status);
						b.putString("age", age);
						b.putString("sex", sex);
						b.putString("location", location);
						b.putString("avatar", avatar);

						Message msg = Message.obtain(null,
								KramlMain.MSG_PRESENCE);
						msg.setData(b);
						try {
							bdd.changeParticipant(from, 
									show, 
									status,
									Integer.parseInt(age), 
									sex, 
									location,
									avatar);
							client.send(msg);
						} catch (RemoteException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				} else if (response_type.equals("user_infos")) {
					JSONObject presences = item.getJSONObject("users");
					Iterator<String> it = presences.keys();
					while (it.hasNext()) {
						JSONArray pres = presences.getJSONArray(it.next());

					}
				} else if (response_type.equals("message")) {

					JSONArray messages = item.getJSONArray("messages");
					for (int j = messages.length() - 1; j >= 0; j--) {
						JSONObject mess = messages.getJSONObject(j);
						String type = mess.getString("type");
						Log.i("KramlService", "Message : " + type);
						if (type.equals("room_infos")) {
							Bundle b = new Bundle();
							b.putString("room_name",
									mess.getString("room_name"));
							Message msg = Message.obtain(null,
									KramlMain.MSG_ROOM_INFO);
							msg.setData(b);
							try {
								bdd.room_name = mess.getString("room_name");
								client.send(msg);
							} catch (RemoteException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							Log.i("KramlService",
									"Send room name to Activity : "
											+ mess.getString("room_name"));
						} else if (type.equals("groupchat")) {
							String from = mess.getString("from");
							String text = mess.getString("text");
							String color = mess.getString("color");

							Bundle b = new Bundle();
							b.putString("from", from);
							b.putString("text", text);
							b.putString("color", color);
							Message msg = Message.obtain(null,
									KramlMain.MSG_GROUPCHAT);
							msg.setData(b);
							try {
								bdd.add_room_message(from, text, color);
								client.send(msg);
							} catch (RemoteException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

							// Notif - Uniquement si message contient le user
							if (text.contains(me)) {
								Intent intent = new Intent(this,
										KramlMain.class);
								PendingIntent pi = PendingIntent.getActivity(
										this, 0, intent, 0);
								noti = new NotificationCompat.Builder(this)
										.setContentTitle("KramL")
										.setContentText(from)
										.setSmallIcon(R.drawable.ic_launcher)
										.setContentIntent(pi)
										.setTicker("New message from " + from)
										.setStyle(
												new NotificationCompat.BigTextStyle()
														.bigText("New message from : "
																+ from
																+ "\n"
																+ text))
										.build();
								noti.vibrate = new long[] { 100, 200, 100, 500 };
								mNM.notify(1, noti);
							}
						}
					}
				} else if (response_type.equals("rooms")) {
					Bundle b = new Bundle();
					b.putString("room_list", item.getString("room_list"));
					Message msg = Message.obtain(null, KramlMain.MSG_ROOM_LIST);
					msg.setData(b);
					try {
						client.send(msg);
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				} else if (response_type.equals("error")) {
					if (item.getString("error_message") != null
							&& item.getString("error_message").equals(
									"user_already_exists")) {
						sendToastToUI("L'utilisateur est déjà enregistré");
						/*
						 * showToast("L'utilisateur est déjà enregistré",
						 * Toast.LENGTH_LONG);
						 */
					} else if (item.getString("error_message") != null
							&& item.getString("error_message").equals(
									"not_connected")) {
						mConnected = false;
						me = "";
						sendMessageToUI(KramlMain.MSG_DISCONNECTED);
					} else {
						sendToastToUI("DEBUG ERROR : " + item.toString());
						// Erreur non gérée
						/*
						 * showToast("DEBUG ERROR : " + item.toString(),
						 * Toast.LENGTH_LONG);
						 */
					}
					/*
					 * if (item.getBoolean("reping")) { ping_again = true; //
					 * txt_output.append("On ping again !!\n"); }
					 */
				} else {
					// DEBUG non gere :
					// showToast("DEBUG : " + item.toString(),
					// Toast.LENGTH_LONG);
				}
			}

			if (ping_again) {
				// txt_output.append("On ping !\n");
				ping();
			}

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			// label_output1.append(response + "\n");
			// showToast("DEBUG : " + response.toString(), Toast.LENGTH_LONG);
			e.printStackTrace();
			// return 99;
		}
		return 1;
	}

	public String postWithHttpClient(KramL_HttpPost hp) {
		return postWithHttpClient(hp.url, hp.params, true);
	}

	public String postWithHttpClient(KramL_HttpPost hp, boolean setCook) {
		return postWithHttpClient(hp.url, hp.params, setCook);
	}

	public String postWithHttpClient(String url, String[][] params,
			boolean setCook) {
		String ret = "";

		Log.i("KramL", url);

		// ret += "Launch : postWithHttpClient => " + url + " : " + setCook
		// + "\n\n";

		// Set timeout only if not ping ^^
		HttpParams httpParameters = new BasicHttpParams();
		if (!url.contains("/ping")) {
			HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
			HttpConnectionParams.setSoTimeout(httpParameters, 10000);
		}
		//

		DefaultHttpClient client = new DefaultHttpClient(httpParameters);
		client.getParams().setParameter("http.useragent", userAgent);

		// PROXY

		if (prox) {
			/*
			 * client.getCredentialsProvider().setCredentials( new
			 * AuthScope("proxy.dtni.macif.fr", 3128), new
			 * UsernamePasswordCredentials("H61451", "H61451"));
			 */

			// HttpHost proxy = new HttpHost("proxy.dtni.macif.fr", 3128);
			HttpHost proxy = new HttpHost("129.181.229.203", 8080);

			client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
					proxy);

		}
		//

		try {
			/*
			 * String [] tab = url.split("http://"); ret += "tab(0) : " + tab[0]
			 * + "\n"; ret += "tab(1) : " + tab[1] + "\n"; ret +=
			 * "URL finale : http://" + URLEncoder.encode(tab[1]) + "\n";
			 */
			HttpPost httppost = new HttpPost(url);

			// Post params
			if (params.length > 0) {
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
						params.length);
				for (int i = 0; i < params.length; i++) {
					nameValuePairs.add(new BasicNameValuePair(params[i][0],
							params[i][1]));
					// ret += "Set param : " + params[i][0] + " = " +
					// params[i][1]
					// + "\n";
				}

				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

			}

			// Set cookie
			if (setCook) {
				/*
				 * for (int i = 0; i < saveHeadersCookie.length; i++) { Header h
				 * = saveHeadersCookie[i]; ret += "Set cookie : " + h.getName()
				 * + " = " + h.getValue() + "\n"; }
				 */
				client.setCookieStore(cookieStore);
				// httppost.setHeaders(saveHeadersCookie);
			}

			HttpResponse response = client.execute(httppost);
			if (response.getStatusLine().getStatusCode() > 500)
				return ret + "Erreur Serveur : "
						+ response.getStatusLine().getStatusCode() + " - "
						+ response.getStatusLine().getReasonPhrase();

			// Get cookie
			cookieStore = client.getCookieStore();
			// saveHeadersCookie = response.getHeaders("Set-Cookie");
			// saveHeadersCookie = new Header[] { response
			// .getLastHeader("Set-Cookie") };
			/*
			 * for (int i = 0; i < saveHeadersCookie.length; i++) { Header h =
			 * saveHeadersCookie[i]; ret += "Get cookie : " + h.getName() +
			 * " = " + h.getValue() + "\n"; }
			 */

			// Get response
			HttpEntity entity = response.getEntity();
			InputStream inputStream = entity.getContent();
			ret += inputStreamToString(inputStream).toString();
		} catch (IllegalArgumentException e) {
			return ret + "IllegalArgumentException : " + url + "\n"
					+ e.getMessage() + "\n";
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			return ret + "UnsupportedEncodingException : " + url + "\n"
					+ e.getMessage() + "\n";

		} catch (Exception e) {
			if (e.getClass().getName()
					.equals("java.net.SocketTimeoutException"))
				return "[{'response':'error', 'message':'" + url
						+ "Request Timeout : KramL not available'}]";
			return ret + "Exception : " + e.getClass().getName() + " : "
					+ e.getMessage();

		} finally {
		}

		return ret;
	}

	// Fast Implementation
	private StringBuilder inputStreamToString(InputStream is) {
		String line = "";
		StringBuilder total = new StringBuilder();

		// Wrap a BufferedReader around the InputStream
		BufferedReader rd = new BufferedReader(new InputStreamReader(is));

		// Read response until the end
		try {
			while ((line = rd.readLine()) != null) {
				total.append(line);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Return full string
		return total;
	}

	private class AjaxCall extends AsyncTask<KramL_HttpPost, Integer, String> {

		@Override
		protected void onCancelled() {
			// TODO Auto-generated method stub
			super.onCancelled();
		}

		@Override
		protected void onPostExecute(String result) {
			// TODO Auto-generated method stub
			super.onPostExecute(result);
			// txt_output.append("Ajax result : " + result + "\n\n");
			parseResponse(result);
			// showDialog("AJAX DONE : " + result);
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			super.onPreExecute();
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			// TODO Auto-generated method stub
			super.onProgressUpdate(values);
		}

		@Override
		protected String doInBackground(KramL_HttpPost... params) {
			// TODO Auto-generated method stub
			int count = params.length;
			String ret = "";
			for (int i = 0; i < count; i++) {
				ret += postWithHttpClient(params[i]);
			}
			return ret;
		}

	}

	private class KramL_HttpPost {
		private String url;
		private String[][] params;

		public KramL_HttpPost(String url, String[][] params) {
			// TODO Auto-generated constructor stub
			this.url = url;
			this.params = params;
		}

		public KramL_HttpPost(String url) {
			// TODO Auto-generated constructor stub
			this.url = url;
			this.params = new String[][] {};
		}

	}

}
